﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Net;
using System.Collections.Specialized;
using jaysJourney_v01.Common;
using jaysJourney_v01.Utils.Levels;
using System.Globalization;

namespace jaysJourney_v01.Utils
{
    public static class WebLoader
    {
        /**
         * MAIN VARIABLES
         */

        private const string STRING_SPLIT = "#b$";
        private const string STRING_BREAK = "#n$";

        /**
         * METHODS
         */

        // Load given user

        public static int loadUser(string username, string password, ActivePlayer player)
        {
            NameValueCollection postData = new NameValueCollection();
            postData.Add("download_mode", "user");
            postData.Add("user_name", username);

            WebClient client = new WebClient();
            byte[] responseArray;
            try
            {
                responseArray = client.UploadValues("http://www.best-designs.at/pro4/WebLoader.php", "POST", postData);
            }
            catch (WebException)
            {
                return -1;
            }
            

            if (Encoding.ASCII.GetString(responseArray) == "") return 0; // no user found

            String[] user = splitUserResponse(Encoding.ASCII.GetString(responseArray));

            if (user[0] == password) // pw is correct
            {
                // parse int
                int money, xp, lvls, mLast, xLast;
                Int32.TryParse(user[1], out money);
                Int32.TryParse(user[2], out xp);
                Int32.TryParse(user[3], out lvls);
                Int32.TryParse(user[4], out mLast);
                Int32.TryParse(user[5], out xLast);

                // set player
                player.setPlayer(username, money, xp, lvls, mLast, xLast, user[6]);
                return 1;
            }

            return 0;
        }

        // check if given username does exist

        public static int doesUserExist(String username)
        {
            NameValueCollection postData = new NameValueCollection();
            postData.Add("download_mode", "user");
            postData.Add("user_name", username);

            WebClient client = new WebClient();

            byte[] responseArray;
            try
            {
                responseArray = client.UploadValues("http://www.best-designs.at/pro4/WebLoader.php", "POST", postData);
            }
            catch (WebException)
            {
                return -1;
            }

            if (Encoding.ASCII.GetString(responseArray) == "") return 0; // no user found

            return 1;
        }

        // refacture userresponse

        private static String[] splitUserResponse(String data)
        {
            String[] user = new String[7];

            int curPos = 0;
            int lastFound = 0;
            for(int i = 0; i < 7; i++)
            {
                lastFound = data.IndexOf(STRING_SPLIT, curPos);
                if (lastFound == -1) user[i] = data.Substring(curPos, data.Length - curPos);
                else user[i] = data.Substring(curPos, lastFound - curPos);
                curPos = lastFound + 3;
            }

            return user;
        }

        // Load the data of a world with the given worldname

        public static string loadWorld(string worldName)
        {
            NameValueCollection postData = new NameValueCollection();
            postData.Add("download_mode", "singleMap");
            postData.Add("world_name", worldName);

            WebClient client = new WebClient();
            byte[] responseArray;
            try
            {
                responseArray = client.UploadValues("http://www.best-designs.at/pro4/WebLoader.php", "POST", postData);
            }
            catch (WebException)
            {
                return null;
            }

            string currentLvl = Encoding.ASCII.GetString(responseArray);

            return currentLvl;
        }

        // Load an Overview of all mapNames

        public static List<string> loadAllMapsNameOnly()
        {
            NameValueCollection postData = new NameValueCollection();
            postData.Add("download_mode", "overview");

            WebClient client = new WebClient();
            byte[] responseArray;
            try
            {
                responseArray = client.UploadValues("http://www.best-designs.at/pro4/WebLoader.php", "POST", postData);
            }
            catch (WebException)
            {
                return null;
            }

            return splitLoadedOverviewMapsOnly(Encoding.ASCII.GetString(responseArray));
        }

        // Helper Method to split mapNames into List

        private static List<string> splitLoadedOverviewMapsOnly(String loadedMapList)
        {
            List<string> mapArray = new List<String>();
            int curPos = 0;
            int lastFound = 0;
            while (lastFound <= loadedMapList.Length - 4)
            {
                lastFound = loadedMapList.IndexOf(STRING_SPLIT, curPos);
                if (lastFound == -1) mapArray.Add(loadedMapList.Substring(curPos, loadedMapList.Length - curPos));
                else mapArray.Add(loadedMapList.Substring(curPos, lastFound - curPos));
                curPos = lastFound + 3;
            }
            return mapArray;
        }

        // Load an detailed Overview of all maps

        public static List<Level> loadAllMaps(int lvl)
        {
            NameValueCollection postData = new NameValueCollection();
            postData.Add("cur_lvl", lvl.ToString());
            postData.Add("download_mode", "overviewFull");

            WebClient client = new WebClient();
            byte[] responseArray;
            try
            {
                responseArray = client.UploadValues("http://www.best-designs.at/pro4/WebLoader.php", "POST", postData);
            }
            catch (WebException)
            {
                return null;
            }
            Debug.WriteLine(Encoding.ASCII.GetString(responseArray));
            return splitLoadedOverview(Encoding.ASCII.GetString(responseArray));
        }

        // Helper Method to split maps into List

        private static List<Level> splitLoadedOverview(String loadedMapList)
        {
            List<Level> mapArray = new List<Level>();
            int curLevelPos = 0;
            int lastFoundLevel = 0;

            while (lastFoundLevel <= loadedMapList.Length - 4) // get whole Level
            {
                lastFoundLevel = loadedMapList.IndexOf(STRING_BREAK, curLevelPos);
                String level = loadedMapList.Substring(curLevelPos, lastFoundLevel - curLevelPos);
                String lvlName = "", size = "", setting = "", creatorName = "", worldCreation = "", recordHolder = "";
                int curPos = 0, lastFound = 0, numStarts = 0, numRates = 0, bestTime = 0, avgBestTime = 0;
                double curRating = 0f;

                if (lastFoundLevel != -1)
                {
                    for (int i = 0; i < 11; i++) // go through string
                    {
                        lastFound = level.IndexOf(STRING_SPLIT, curPos);
                        switch (i)
                        {
                            case 0: lvlName = level.Substring(curPos, lastFound - curPos); break; // worldname
                            case 1: creatorName = level.Substring(curPos, lastFound - curPos); break; // creatorName
                            case 2: setting = level.Substring(curPos, lastFound - curPos); break; // setting
                            case 3: size = level.Substring(curPos, lastFound - curPos); break; // size
                            case 4: Int32.TryParse(level.Substring(curPos, lastFound - curPos), out numStarts); break; // numRatings
                            case 5: Int32.TryParse(level.Substring(curPos, lastFound - curPos), out numRates); break; // numRatings
                            case 6:
                                double.TryParse(level.Substring(curPos, lastFound - curPos), out curRating);
                                //curRating = System.Convert.ToDouble(level.Substring(curPos, lastFound - curPos));
                                curRating = curRating / 1000000d;
                                break; // curRating
                            case 7: worldCreation = level.Substring(curPos, lastFound - curPos); break; // creationDate
                            case 8: Int32.TryParse(level.Substring(curPos, lastFound - curPos), out bestTime); break; // bestTime
                            case 9: recordHolder = level.Substring(curPos, lastFound - curPos); break; // recordholder
                            case 10: Int32.TryParse(level.Substring(curPos, level.Length - curPos), out avgBestTime); break; // bestTime
                            default: break;
                        }
                        curPos = lastFound + 3;
                    }
                    mapArray.Add(new Level(lvlName, setting, size, creatorName, numStarts, numRates, curRating, worldCreation, bestTime, recordHolder, avgBestTime));
                }
                curLevelPos = lastFoundLevel + 3;
            }

            return mapArray;
        }

        public static int getPersonalBest(String worldname, String username)
        {
            NameValueCollection postData = new NameValueCollection();
            postData.Add("download_mode", "personalBest");
            postData.Add("world_name", worldname);
            postData.Add("username", username);

            WebClient client = new WebClient();
            byte[] responseArray;
            try
            {
                responseArray = client.UploadValues("http://www.best-designs.at/pro4/WebLoader.php", "POST", postData);
            }
            catch (WebException)
            {
                return -1;
            }

            int returnValue;
            Int32.TryParse(Encoding.ASCII.GetString(responseArray), out returnValue);
            return returnValue;
        }
    }
}
